<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue';
import { getOpenAIStreamResponse } from '@/services/openai';

// 悬浮球位置状态
const floatingBallPosition = ref({ x: window.innerWidth - 80, y: window.innerHeight - 80 });
const isDragging = ref(false);
const dragOffset = ref({ x: 0, y: 0 });

// 弹窗状态
const isChatOpen = ref(false);
const userInput = ref('');
const response = ref({ answer: '' });
const isLoading = ref(false);
const error = ref(null);
const abortController = ref(null);

// 悬浮球拖动逻辑
const startDrag = (e) => {
  if (e.type === 'mousedown') {
    isDragging.value = true;
    dragOffset.value = {
      x: e.clientX - floatingBallPosition.value.x,
      y: e.clientY - floatingBallPosition.value.y
    };
  } else if (e.type === 'touchstart') {
    isDragging.value = true;
    const touch = e.touches[0];
    dragOffset.value = {
      x: touch.clientX - floatingBallPosition.value.x,
      y: touch.clientY - floatingBallPosition.value.y
    };
  }
};

const dragBall = (e) => {
  if (!isDragging.value) return;
  
  let clientX, clientY;
  if (e.type === 'mousemove') {
    clientX = e.clientX;
    clientY = e.clientY;
  } else if (e.type === 'touchmove') {
    const touch = e.touches[0];
    clientX = touch.clientX;
    clientY = touch.clientY;
  }
  
  floatingBallPosition.value = {
    x: clientX - dragOffset.value.x,
    y: clientY - dragOffset.value.y
  };
};

const stopDrag = () => {
  isDragging.value = false;
};

// 弹窗操作
const openChat = () => {
  isChatOpen.value = true;
  userInput.value = '';
  response.value = { answer: '' };
  error.value = null;
};

const closeChat = () => {
  isChatOpen.value = false;
  cancelRequest(); // 关闭时取消任何正在进行的请求
};

// 对话逻辑
const submitQuestion = async () => {
  if (!userInput.value.trim()) return;
  
  // 重置状态
  isLoading.value = true;
  error.value = null;
  response.value = { answer: '' };
  
  // 创建新的AbortController用于取消请求
  abortController.value = new AbortController();
  
  try {
    await getOpenAIStreamResponse(
      userInput.value,
      (content) => {
        // 实时更新响应内容
        response.value.answer += content;
      },
      abortController.value.signal
    );
  } catch (err) {
    error.value = `请求失败: ${err.message}`;
  } finally {
    isLoading.value = false;
    abortController.value = null;
  }
};

const cancelRequest = () => {
  if (abortController.value) {
    abortController.value.abort();
    isLoading.value = false;
    abortController.value = null;
    
    // 保留已接收到的部分答案
    if (!response.value.answer) {
      response.value.answer = '请求已取消';
    }
  }
};

// 响应窗口大小变化，防止悬浮球移出可视区域
const handleResize = () => {
  floatingBallPosition.value = {
    x: Math.min(floatingBallPosition.value.x, window.innerWidth - 60),
    y: Math.min(floatingBallPosition.value.y, window.innerHeight - 60)
  };
};

// 添加事件监听器
onMounted(() => {
  window.addEventListener('resize', handleResize);
  document.addEventListener('mousemove', dragBall);
  document.addEventListener('touchmove', dragBall, { passive: false });
  document.addEventListener('mouseup', stopDrag);
  document.addEventListener('touchend', stopDrag);
});

// 移除事件监听器
onBeforeUnmount(() => {
  window.removeEventListener('resize', handleResize);
  document.removeEventListener('mousemove', dragBall);
  document.removeEventListener('touchmove', dragBall);
  document.removeEventListener('mouseup', stopDrag);
  document.removeEventListener('touchend', stopDrag);
  cancelRequest();
});
</script>

<template>
  <!-- 悬浮球 -->
  <div 
    class="floating-ball"
    :style="{ 
      left: `${floatingBallPosition.x}px`, 
      top: `${floatingBallPosition.y}px`,
      cursor: isDragging ? 'grabbing' : 'grab'
    }"
    @mousedown="startDrag"
    @touchstart="startDrag"
    @click="openChat"
    @touchmove.prevent
  >
    <div class="ball-icon">
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
        <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path>
      </svg>
    </div>
  </div>
  
  <!-- 聊天弹窗 -->
  <div v-if="isChatOpen" class="chat-modal">
    <div class="modal-backdrop" @click="closeChat"></div>
    
    <div class="modal-content">
      <div class="modal-header">
        <h3>AI 助手</h3>
        <button class="close-btn" @click="closeChat">
          <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
            <line x1="18" y1="6" x2="6" y2="18"></line>
            <line x1="6" y1="6" x2="18" y2="18"></line>
          </svg>
        </button>
      </div>
      
      <div class="chat-container">
        <div v-if="response.answer" class="response-container">
          <div class="answer">
            <pre class="streaming-content">{{ response.answer }}</pre>
          </div>
        </div>
        
        <div class="input-group">
          <input 
            v-model="userInput"
            placeholder="输入问题..."
            @keyup.enter="submitQuestion"
            :disabled="isLoading"
          />
          <div class="button-group">
            <button 
              @click="submitQuestion" 
              :disabled="isLoading"
              class="submit-btn"
            >
              {{ isLoading ? '生成中...' : '发送' }}
            </button>
            <button 
              v-if="isLoading"
              @click="cancelRequest"
              class="cancel-btn"
            >
              停止
            </button>
          </div>
        </div>
        
        <div v-if="error" class="error">{{ error }}</div>
      </div>
    </div>
  </div>
</template>

<style scoped>
/* 悬浮球样式 */
.floating-ball {
  position: fixed;
  width: 60px;
  height: 60px;
  background: #409eff;
  border-radius: 50%;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: grab;
  z-index: 1000;
  transition: transform 0.2s, box-shadow 0.2s;
}

.floating-ball:hover {
  transform: scale(1.05);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.2);
}

.ball-icon {
  color: white;
  font-weight: bold;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* 弹窗样式 */
.chat-modal {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1001;
}

.modal-backdrop {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.3);
  backdrop-filter: blur(4px);
}

.modal-content {
  position: relative;
  width: 90%;
  max-width: 500px;
  max-height: 80vh;
  background: #fafafad0;
  border-radius: 16px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  z-index: 1002;
}

.modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 20px;
  background: #ffffff;
  color: #303133;
}

.modal-header h3 {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
}

.close-btn {
  background: transparent;
  border: none;
  color: #303133;
  cursor: pointer;
  padding: 4px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.close-btn:hover {
  background: rgba(255, 255, 255, 0.2);
}

/* 聊天容器 */
.chat-container {
  display: flex;
  flex-direction: column;
  flex: 1;
  padding: 0 20px 20px;
  overflow: hidden;
  gap: 24px;
}

.response-container {
  flex: 1;
  margin-top: 0; 
  padding: 20px; 
  border-radius: 12px;
  background: #f8f9fa;
  border: 1px solid #e9ecef;
  overflow-y: auto;
  max-height: 300px;
}

.streaming-content {
  white-space: pre-wrap;
  line-height: 1.6;
  font-size: 16px;
  margin: 0;
  padding-top: 12px;
}

.input-group {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin-top: 20px;
}

.button-group {
  display: flex;
  gap: 10px;
}

input {
  flex: 1;
  padding: 14px;
  border: 1px solid #dee2e6;
  border-radius: 12px;
  font-size: 16px;
  transition: border-color 0.2s;
}

input:focus {
  border-color: #409eff;;
  outline: none;
  box-shadow: 0 0 0 3px rgba(66, 66, 185, 0.2);
}

button {
  padding: 10px 16px;
  border: none;
  border-radius: 12px;
  cursor: pointer;
  font-weight: 500;
  font-size: 14px;
  transition: all 0.2s;
}

.submit-btn {
  background: #409eff;;
  color: white;
  flex: 1;
}

.submit-btn:not(:disabled):hover {
  background: #409eff;;
}

.submit-btn:disabled {
  background: #409eff;;
  cursor: not-allowed;
}

.cancel-btn {
  background: #ff6b6b;
  color: white;
  flex: 1;
}

.cancel-btn:hover {
  background: #ff5252;
}

.error {
  color: #ff5252;
  padding: 10px;
  background: #fff0f0;
  border-radius: 8px;
  margin-top: 10px;
  font-size: 14px;
  border: 1px solid #ffd1d1;
}

/* 响应式调整 */
@media (max-width: 600px) {
  .modal-content {
    width: 95%;
    max-height: 85vh;
  }
  
  .response-container {
    max-height: 200px;
  }
}
</style>